package io.gitee.jingtuo.android.device.ui.main

import android.content.Context
import android.os.Build
import android.util.Log
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.huawei.agconnect.AGCRoutePolicy
import com.huawei.agconnect.AGConnectInstance
import com.huawei.agconnect.AGConnectOptionsBuilder
import com.huawei.agconnect.auth.AGConnectAuth
import com.huawei.agconnect.cloud.database.AGConnectCloudDB
import com.huawei.agconnect.cloud.database.CloudDBZone
import com.huawei.agconnect.cloud.database.CloudDBZoneConfig
import com.huawei.agconnect.cloud.database.CloudDBZoneQuery
import com.huawei.hmf.tasks.OnFailureListener
import com.huawei.hmf.tasks.OnSuccessListener
import io.gitee.jingtuo.android.device.SysProManager
import io.gitee.jingtuo.android.device.dataStore
import io.gitee.jingtuo.android.device.model.ObjectTypeInfoHelper
import io.gitee.jingtuo.android.device.model.SysPro
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.UUID

class MainViewModel : ViewModel() {

    private val mDeviceInfo = MutableStateFlow(mutableListOf<DeviceInfoItem>())

    private val mUploadState = MutableStateFlow(Pair<String, String>("none", ""))

    fun deviceInfo(): StateFlow<List<DeviceInfoItem>> {
        return mDeviceInfo.asStateFlow()
    }

    fun loadDeviceInfo() {
        val deviceNamePair = SysProManager.getDeviceName()

        val list = mutableListOf<DeviceInfoItem>()
        //设备名称
        list.add(DeviceInfoItem(name = "名称", deviceNamePair ?: Pair("", "")))
        //设备品牌
        list.add(DeviceInfoItem("品牌", Pair("ro.product.brand", Build.BRAND)))
        //设备制造商
        list.add(DeviceInfoItem("制造商", Pair("ro.product.manufacturer", Build.MANUFACTURER)))
        //设备型号
        list.add(DeviceInfoItem("型号", Pair("ro.product.model", Build.MODEL)))
        //系统名称
        list.add(DeviceInfoItem("系统名称", SysProManager.getBrandOSName()))
        //系统版本
        list.add(DeviceInfoItem("系统版本", SysProManager.getBrandOSVersion()))
        //Android系统版本
        list.add(DeviceInfoItem("Android版本", Pair("ro.build.version.release", Build.VERSION.RELEASE)))
        //Android API
        list.add(DeviceInfoItem("Android API", Pair("ro.build.version.sdk", "${Build.VERSION.SDK_INT}")))
        mDeviceInfo.update {
            list
        }
    }

    fun uploadDeviceData(context: Context) {
        viewModelScope.launch {
            val uid = AGConnectAuth.getInstance().currentUser?.uid
            if (uid.isNullOrEmpty()) {
                return@launch
            }
            mUploadState.update {
                it.copy(first = "uploading", "")
            }
            //云数据库
            AGConnectCloudDB.initialize(context.applicationContext)
            AGConnectInstance.buildInstance(
                AGConnectOptionsBuilder()
                    .setRoutePolicy(AGCRoutePolicy.CHINA)
                    .build(context.applicationContext)
            )
            val cloudDB = AGConnectCloudDB.getInstance(
                AGConnectInstance.getInstance(),
                AGConnectAuth.getInstance()
            )
            cloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
            //存储区
            val zoneConfig = CloudDBZoneConfig(
                "AndroidDevice",
                CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
                CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC
            )
            zoneConfig.persistenceEnabled = true
            var cloudDBZone: CloudDBZone? = null
            //此处使用同步
            val uuidKey = stringPreferencesKey("uuid")
            var uuid = context.dataStore.data.map {
                it[uuidKey]?: ""
            }.firstOrNull()
            cloudDB.openCloudDBZone2(zoneConfig, true)
                .addOnSuccessListener(OnSuccessListener {
                    cloudDBZone = it
                })
                .onSuccessTask {
                    Log.i("AGCloudDB", "1 Thread.name ${Thread.currentThread().name}")
                    it.runTransaction { transaction ->
                        if (uuid.isNullOrEmpty()) {
                            //生成uuid
                            uuid = UUID.randomUUID().toString()
                        } else {
                            //删除历史数据
                            val oldProps = transaction.executeQuery(CloudDBZoneQuery.where(SysPro::class.java)
                                .equalTo("uid", uid).and().equalTo("uuid", uuid as String))
                            transaction.executeDelete(oldProps)
                        }
                        //插入数据
                        //插入属性数据
                        val propList = mutableListOf<SysPro>()
                        val keyList = arrayOf(
                            "ro.product.brand",
                            "ro.product.manufacturer",
                            "ro.product.model",
                            "ro.build.version.release",
                            "ro.build.version.sdk",
                            "mscw.hnouc.patch.version",
                            "persist.sys.grant_version",
                            "ro.vivo.product.version")
                        for (key in keyList) {
                            val value = SysProManager.getProperty(key)
                            if (!value.isEmpty()) {
                                val sysPro = SysPro()
                                sysPro.uid = uid
                                sysPro.uuid = uuid
                                sysPro.key = key
                                sysPro.value = value
                                propList.add(sysPro)
                            }
                        }
                        //特殊属性: 设备名称
                        val pair = SysProManager.getDeviceName()
                        if (pair != null) {
                            val sysPro = SysPro()
                            sysPro.uid = uid
                            sysPro.uuid = uuid
                            sysPro.key = pair.first
                            sysPro.value = pair.second
                            propList.add(sysPro)
                        }
                        transaction.executeUpsert(propList)
                        true
                    }
                }
                .addOnSuccessListener(OnSuccessListener {
                    //保存uuid
                    viewModelScope.launch {
                        withContext(Dispatchers.IO) {
                            context.dataStore.edit {
                                it[uuidKey] = uuid!!
                            }
                            withContext(Dispatchers.Main) {
                                mUploadState.update {
                                    it.copy(first = "success", "")
                                }
                            }
                        }
                    }
                })
                .addOnFailureListener(OnFailureListener { error ->
                    mUploadState.update {
                        it.copy(first = "failure", error.message?:"Unknown")
                    }
                })
                .addOnCompleteListener {
                    //关闭存储区
                    cloudDB.closeCloudDBZone(cloudDBZone)
                }
        }
    }

    /**
     * 上传状态
     */
    fun uploadState(): StateFlow<Pair<String, String>> {
        return mUploadState.asStateFlow()
    }

    fun resetUploadState() {
        mUploadState.update {
            it.copy(first = "none", "")
        }
    }
}